#include "tracking.h"

// This will find the overlapping between dres_in(f1i) and all
// detection windows in dres_in(f2)

extern time_t t_calc_overlap;

ores calc_overlap(const dres &dres1, int f1i,const dres &dres2, 
	int* f2, int nf2) {
	time_t tt = time(NULL);

	int n = nf2, m = 0, *inds;
	double cx1, cx2, cy1, cy2, ca;
	double *gx1, *gx2, *gy1, *gy2, *ga, *ov, *ov_n1, *ov_n2, *inter, *u;
	double *w, *h;
	ores result;

	gx1 = new double[n];
	gx2 = new double[n];
	gy1 = new double[n];
	gy2 = new double[n];
	ga = new double[n];
	ov = new double[n];
	ov_n1 = new double[n];
	ov_n2 = new double[n];
	w = new double[n];
	h = new double[n];
	inds = new int[n];
	inter = new double[n];
	u = new double[n];

	cx1 = dres1.x[f1i];
	cx2 = dres1.x[f1i] + dres1.w[f1i] - 1;
	cy1 = dres1.y[f1i];
	cy2 = dres1.y[f1i] + dres1.h[f1i] - 1;

	for (int i = 0; i < n; i++) {
		gx1[i] = dres2.x[f2[i]];
		gx2[i] = dres2.x[f2[i]] + dres2.w[f2[i]] - 1;
		gy1[i] = dres2.y[f2[i]];
		gy2[i] = dres2.y[f2[i]] + dres2.h[f2[i]] - 1;
	}

	ca = dres1.h[f1i] * dres1.w[f1i];
	for (int i = 0; i < n; i++) 
		ga[i] = dres2.h[f2[i]] * dres2.w[f2[i]];
	

	for (int i = 0; i < n; i++) {
		// Find the overlapping area
		w[i] = min(cx2, gx2[i]) - max(cx1, gx1[i]) + 1;
		h[i] = min(cy2, gy2[i]) - max(cy1, gy1[i]) + 1;
		// Real Overlap
		if (w[i]>0 && h[i] > 0) {
			inds[m] = i;
			m++;
		}
		// Set ov, ov_n1, ov_n2 to zeros
		ov[i] = 0;
		ov_n1[i] = 0;
		ov_n2[i] = 0;
	}
	
	for (int i = 0; i < m; i++) {
		inter[i]= w[inds[i]] * h[inds[i]]; // area of overlap
		u[i] = ca + ga[inds[i]] - w[inds[i]] * h[inds[i]]; // area of union

		ov[inds[i]] = inter[i] / u[i];
		ov_n1[inds[i]] = inter[i] / ca;
		ov_n2[inds[i]] = inter[i] / ga[inds[i]];
	}

	result.ov = ov;
	result.ov_n1 = ov_n1;
	result.ov_n2 = ov_n2;
	result.size = n;

	delete[]gx1;
	delete[]gx2;
	delete[]gy1;
	delete[]gy2;
	delete[]w;
	delete[]h;
	delete[]u;
	delete[]inds;
	delete[]inter;

	t_calc_overlap += time(NULL) - tt;
	return result;
}